package network

import (
	"bytes"
	"strconv"
	"sync"
	"encoding/binary"
	"time"
)

type StringBoolMap struct {
	m map[string]bool
	sync.RWMutex
}

func (s *StringBoolMap) Init() {
	s.Lock()
	defer s.Unlock()
	s.m = make(map[string]bool)
}

func (s *StringBoolMap) Delete(key string) {
	s.Lock()
	defer s.Unlock()
	_, exist := s.m[key]
	if exist {
		delete(s.m, key)
	}
}

func (s *StringBoolMap) Get(key string) (bool, bool) {
	s.Lock()
	defer s.Unlock()
	_, exist := s.m[key]
	if exist {
		return s.m[key], true
	}
	return false, false
}

func (s *StringBoolMap) Insert(key string, value bool) {
	s.Lock()
	defer s.Unlock()
	s.m[key] = value
}

func (s *StringBoolMap) GetAll() map[string]bool {
	return s.m
}

type StringIntMap struct {
	m map[string]int
	sync.RWMutex
}

func (s *StringIntMap) Init() {
	s.Lock()
	defer s.Unlock()
	s.m = make(map[string]int)
}

func (s *StringIntMap) Get(key string) (int, bool) {
	s.Lock()
	defer s.Unlock()
	_, exist := s.m[key]
	if exist {
		return s.m[key], true
	}
	return 0, false
}

func (s *StringIntMap) Insert(key string, value int) {
	s.Lock()
	defer s.Unlock()
	s.m[key] = value
}

func (s *StringIntMap) Delete(key string) {
	_, exist := s.Get(key)
	if exist {
		s.Lock()
		defer s.Unlock()
		delete(s.m, key)
	}
}

// Utility functions
func Int64ToString(input int64) string {
	return strconv.FormatInt(input, 10)
}

func StringToInt64(input string) (int64, error) {
	return strconv.ParseInt(input, 10, 64)
}

func IntToString(input int) string {
	return strconv.Itoa(input)
}

func IntToBytes(n int) []byte {
	data := int64(n)
	bytebuf := bytes.NewBuffer([]byte{})
	binary.Write(bytebuf, binary.BigEndian, data)
	return bytebuf.Bytes()
}

func BytesToString(input []byte) string {
	return string(input[:])
}

func MakeTimestamp() int64 {
	return time.Now().UnixNano() / int64(time.Millisecond)
}

